import requests
import execjs
from bs4 import BeautifulSoup
import re


# 代理IP
# https://www.docip.net/#index
# https://www.kuaidaili.com/free/intr/

class BaiduTranslate(object):
    def __init__(self, query):
        """初始化post参数"""
        self.query = query  # 要查询的数据
        self.url_init = "https://fanyi.baidu.com/"  # 首次访问百度翻译的地址
        self.url = "https://fanyi.baidu.com/v2transapi"  # 实际翻译获取信息的地址
        self.header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
            'cookie': ""  # 首次访问后，从返回信息中获取
        }
        self.data = {
            "from": "en",
            "to": "zh",
            "query": self.query,  # 需要查询的数据
            "simple_means_flag": "3",
            "sign": "",  # 用venvquery值，通过调用js进行计算
            "token": "",  # 第二次访问百度翻译后的返回值中获取
            "domain": "common",
            "ts": ""  # 日期时间戳，从js中获取
        }

    def structure_form(self):
        """计算sign值，及获取时间戳"""
        with open('baidu_translata_js.js', 'r', encoding='utf-8') as f:
            ctx = execjs.compile(f.read())
        self.data['sign'] = ctx.call('e', self.query)
        self.data['ts'] = ctx.call('ts')

    def get_response(self):
        """请求翻译，并获取翻译后的返回信息，解析后返回翻译结果"""
        self.structure_form()
        self.get_cookie_token()
        response = requests.post(self.url, headers=self.header, data=self.data)
        response.encoding = "utf-8"
        r_json_data = response.json()
        r_data = r_json_data['trans_result']['data'][0]['dst']
        return r_data

    def get_baidu_fanyi_cookie(self):
        """从第一次访问百度翻译的返回值中获取cookie"""
        response = requests.get(self.url_init, headers=self.header)
        print("====================")
        print(response.headers)
        response.encoding = "utf-8"
        self.header['cookie'] = response.headers['Set-Cookie']

    def get_baidu_fanyi_token(self):
        """从第二次访问的返回信息中获取token"""
        response = requests.get(self.url_init, headers=self.header)
        response.encoding = "utf-8"
        # print("-------------------------")
        # print(response.text)
        # 获取返回值中所有script脚本，token在window['common'] = {中
        soup = BeautifulSoup(response.text, 'html.parser')
        scripts = soup.find_all('script')
        # print(scripts)

        # 搜索script中token信息，token信息样例为：
        #     token: '9922fea9157d09cbfc1eb70d3609062b',
        # token信息前有空格，最后有逗号
        for script in scripts:
            pattern = r'token\s*:\s*(.*)'  # 匹配带有前空格的token
            match = re.search(pattern, script.get_text())
            if match:
                token_msg = match.group(1).strip()  # 获取配信息
                token_msg = token_msg.rstrip(',')  # 删除结尾的逗号
                token_msg = token_msg.replace("'", "")  # 替换单引号
                # print(token_msg)
                self.data['token'] = token_msg

    def get_cookie_token(self):
        """
            百度翻译首次访问时，request header没有cookie信息。
            需要从首次返回值中的Set-Cookie项中获取，
            第二次访问时，request header带cookie信息后，
            返回信息中含有token信息。
            在之后的访问中，必须将这两个值，设置在请求头中，才会返回成功信息。
        """

        # 第一次访问，获取cookie信息
        self.get_baidu_fanyi_cookie()
        # 第二次访问，获取token
        self.get_baidu_fanyi_token()


if __name__ == '__main__':
    baidu_translate_spider = BaiduTranslate('this my student')
    result = baidu_translate_spider.get_response()
    print(result)
